﻿using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using SHKF.B2C.JuShuiTan.BLL;
using SHKF.B2C.JuShuiTan.Model;
using SHKF.B2C.JuShuiTan.Model.Entity;
using SHKF.B2C.JuShuiTan.Model.Inter;
using SHKF.B2C.JuShuiTan.Model.Inter.CombineSkuQuery;
using SHKF.B2C.JuShuiTan.Model.Inter.InventoryV2;
using SHKF.B2C.JuShuiTan.Model.Inter.ItemskuUpload;
using SHKF.B2C.JuShuiTan.Model.Inter.OrdersQuery;
using SHKF.B2C.JuShuiTan.Model.Inter.ShopQuery;
using SHKF.B2C.JuShuiTan.Model.Inter.TaoBao;
using SHKF.B2C.Model;
using SHKF.B2C.Model.Dto;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace SHKF.B2C.JuShuiTan.Network
{
    public class JSTClient : HttpClient
    {
        protected string app_key = "a3b0232cfe6043248a4b3a8dacf89e14";
        protected string app_secret = "3815648e612241ddb9b0d10618843324";
        protected string access_token = "";
        protected string urlRefreshToken = "/openWeb/auth/refreshToken";
        protected string CS;
        public string CompanyID;

        private string urlShopQuery = "/open/shops/query";                              //店铺查询
        private string urlInventoryv2Upload = "/open/jushuitan/inventoryv2/upload";  //新建盘点单-新
        private string urlItemSku = "/open/jushuitan/itemsku/upload";                //普通商品上传
        private string urlCombineSkuQuery = "/open/combine/sku/query";               //组合装商品查询

        private string urlOrdersQuery = "/open/orders/single/query";                 //订单查询（非淘系订单查询）

        private string urlOrdersQueryTaoBao = "http://a1q40taq0j.api.taobao.com/router/qm";



        public JSTClient()
        { 
            
        }

        protected void Init()
        {
            if (CS == "1")
            {
                this.app_key = "b0b7d1db226d4216a3d58df9ffa2dde5";
                this.app_secret = "99c4cef262f34ca882975a7064de0b87";

                base.BaseAddress = new Uri("https://dev-api.jushuitan.com");
            }
            else
            {
                //base.BaseAddress = new Uri("https://openweb.jushuitan.com");
                base.BaseAddress = new Uri("https://openapi.jushuitan.com");
            }
        }

        public async Task<BaseDto> ShopsQuery(ShopsQueryParam data)
        {
            string biz = JsonConvert.SerializeObject(data);
            return await this.Post<BaseDto>(urlShopQuery, biz);
        }

        /// <summary>
        /// 盘点
        /// </summary>
        public async Task<InventoryUploadDto> InventoryvUpload(InventoryUploadParam data)
        {
            try
            {
                string biz = JsonConvert.SerializeObject(data);
                InventoryUploadDto dto = await this.Post<InventoryUploadDto>(this.urlInventoryv2Upload, biz);
                return dto;
            }
            catch (Exception ex)
            { 
                throw ex;
            } 
        }

        /// <summary>
        /// 普通商品资料
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task<BaseDto> ItemSkuUpload(ItemSkuParam data)
        {
            try
            {
                string biz = JsonConvert.SerializeObject(data);
                BaseDto dto = await this.Post<BaseDto>(this.urlItemSku, biz);
                return dto;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 组合装商品查询
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task<CombineSkuQueryDto> CombineSkuQuery(CombineSkuQueryParam data)
        {
            try
            {
                string biz = JsonConvert.SerializeObject(data);
                CombineSkuQueryDto dto = await this.Post<CombineSkuQueryDto>(this.urlCombineSkuQuery, biz);
                return dto;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }


        /// <summary>
        ///　查询定单
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task<OrderDto> OrderQeury(OrdersSingleParam data)
        {
            try
            {
                string biz = JsonConvert.SerializeObject(data);
                OrderDto dto = await this.Post<OrderDto>(this.urlOrdersQuery, biz);
                return dto;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

      
        private async Task<T> Post<T>(string api, string biz) where T: BaseDto, new()
        {
            await this.GetToken();
            if(string.IsNullOrEmpty(access_token))
            {
                return (T)new BaseDto() { code = -1, msg = "token为空" };
            }

            string time = Math.Floor(this.GetTimeStamp()).ToString();
            string requestUri = base.BaseAddress.OriginalString + api;
            Dictionary<string, string> ht = new Dictionary<string, string>();
            ht.Add("access_token", access_token);
            ht.Add("app_key", this.app_key);
            ht.Add("biz", biz);
            ht.Add("charset", "utf-8");
            ht.Add("timestamp", time);
            ht.Add("version", "2");

            string sign = this.getSign(app_secret, ht);
            ht.Add("sign", sign);
            string text = this.GetParamData(ht); 
            StringContent content = new StringContent(text, Encoding.UTF8);
            content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
            HttpResponseMessage httpResponseMessage = await base.PostAsync(requestUri, content);
            if (httpResponseMessage.IsSuccessStatusCode)
            {
                string str = await httpResponseMessage.Content.ReadAsStringAsync();
                try
                {
                    T result = await httpResponseMessage.Content.ReadAsAsync<T>();
                    return result;
                }
                catch (Exception ex)
                {
                    T exInfo = new T();
                    exInfo.code = -1;
                    exInfo.msg = ex.Message;
                    return exInfo;
                }
                
            }
            else
            {
                BaseDto error = await httpResponseMessage.Content.ReadAsAsync<BaseDto>();
                return (T)error;
            } 
        }

        protected virtual async Task<string> GetToken()
        { 
            return await Task.FromResult<string>("");
        }
         
        protected double GetTimeStamp()
        {
            DateTime timeStampStartTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

            DateTime now = DateTime.Now;
            double timestamp = (now.ToUniversalTime() - timeStampStartTime).TotalSeconds;
            return timestamp;
        }

        protected string getSign(string signKey, Dictionary<string, string> param)
        {
            ArrayList keys = new ArrayList(param.Keys);
            keys.Sort(); //按字母顺序进行排序
            string resultStr = "";
            foreach (string key in keys)
            {
                if (key != null && key != "" && key != "sign")
                {
                    resultStr = resultStr + key + param[key];
                }
            }
            resultStr = signKey + resultStr;
            MD5 md5 = MD5.Create();
            byte[] rstRes = md5.ComputeHash(Encoding.UTF8.GetBytes(resultStr));
            string hex = BitConverter.ToString(rstRes, 0).Replace("-", string.Empty).ToLower();

            return hex; 
        }

        protected string GetParamData(Dictionary<string, string> ht)
        { 
            string str = "";
            foreach (KeyValuePair<string,string> items in ht)
            { 
                str += items.Key.ToString() + "=" + System.Web.HttpUtility.UrlEncode(items.Value.ToString(), System.Text.Encoding.UTF8) + "&";
            }

            return str.Substring(0, str.Length - 1);
        }

        
        public async Task<OrderListDto> TaoBaoOrderQeury(int pageIndex, int pageSize, DateTime startTime, DateTime endTime)
        {
            Dictionary<string, string> param = new Dictionary<string, string>();
            param.Add("page_index", pageIndex.ToString());
            param.Add("page_size", pageSize.ToString());
            param.Add("start_time", startTime.ToString("yyyy-MM-dd HH:mm:ss"));
            param.Add("end_time", endTime.ToString("yyyy-MM-dd HH:mm:ss"));

            string session = ""; 
            OrderListDto dto = await Post<OrderListDto>("jushuitan.order.list.query", session, param); 
            return dto;
        }

        private async Task<string> GetSession()
        {
            //获取code
            string url = $"https://oauth.taobao.com/authorize?response_type=code&client_id=32305619&redirect_uri=https://www.baidu.com/&view=web"; 
            HttpResponseMessage httpResponseMessage = await base.GetAsync(url);
            if (httpResponseMessage.IsSuccessStatusCode)
            {
                string str = await httpResponseMessage.Content.ReadAsStringAsync();
            }
            else
            {
                BaseDto error = await httpResponseMessage.Content.ReadAsAsync<BaseDto>();

            }


            return "";
        }

        private async Task<T> Post<T>(string method, string session, IDictionary<string, string> param) where T : BaseDto, new()
        {
            #region -----API系统参数---- 

            param.Add("target_app_key", "23060081"); 
            param.Add("customer_id", "12318452");

            param.Add("app_key", "32305619");
            param.Add("method", method);
            param.Add("session", session);
            param.Add("timestamp", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
            param.Add("format", "json");
            param.Add("v", "2.0");
            param.Add("sign_method", "md5");
            param.Add("sign", CreateSign(param, "007274989b16e8151e548b0f41d5c3db"));

            #endregion

            #region ---- 完成 HTTP POST 请求----

            string text = this.Sort(param);
            StringContent content = new StringContent(text, Encoding.UTF8);
            content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
            HttpResponseMessage httpResponseMessage = await base.PostAsync(urlOrdersQueryTaoBao, content);
            if (httpResponseMessage.IsSuccessStatusCode)
            {
                string str = await httpResponseMessage.Content.ReadAsStringAsync();
                string json = Regex.Replace(str, @"[\x00-\x08\x0b-\x0c\x0e-\x1f]", "");
                 
                try
                {
                    T result = JsonConvert.DeserializeObject<T>(json);// await httpResponseMessage.Content.ReadAsAsync<T>();
                    return result;
                }
                catch (Exception ex)
                {
                    T exInfo = new T();
                    exInfo.code = -1;
                    exInfo.msg = ex.Message;
                    return exInfo;
                } 
            }
            else
            {
                BaseDto error = await httpResponseMessage.Content.ReadAsAsync<BaseDto>();
                return (T)error;
            }


           // string result = string.Empty;

            //HttpWebRequest req = (HttpWebRequest)WebRequest.Create(urlOrdersQueryTaoBao);
            //req.Method = "POST";
            //req.KeepAlive = true;
            //req.Timeout = 300000;
            //req.ContentType = "application/x-www-form-urlencoded;charset=utf-8";

            //byte[] postData = Encoding.UTF8.GetBytes(Sort(param));
            //Stream reqStream = req.GetRequestStream();
            //reqStream.Write(postData, 0, postData.Length);
            //reqStream.Close();
            //HttpWebResponse rsp = (HttpWebResponse)req.GetResponse();
            //Encoding encoding = Encoding.GetEncoding(rsp.CharacterSet);
            //Stream stream = null;
            //StreamReader reader = null;
            //stream = rsp.GetResponseStream();
            //reader = new StreamReader(stream, encoding);
            //result = reader.ReadToEnd();
            //if (reader != null) reader.Close();
            //if (stream != null) stream.Close();
            //if (rsp != null) rsp.Close();

            #endregion

            //string json = Regex.Replace(result, @"[\x00-\x08\x0b-\x0c\x0e-\x1f]", "");
            //return json;

        }

        private string Sort(IDictionary<string, string> parameters)
        {
            StringBuilder postData = new StringBuilder();
            bool hasParam = false;
            IEnumerator<KeyValuePair<string, string>> dem = parameters.GetEnumerator();
            while (dem.MoveNext())
            {
                string name = dem.Current.Key;
                string value = dem.Current.Value;

                // 忽略参数名或参数值为空的参数 
                if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(value))
                {
                    if (hasParam)
                    {
                        postData.Append("&");
                    }
                    postData.Append(name);
                    postData.Append("=");
                    postData.Append(Uri.EscapeDataString(value));
                    hasParam = true;
                }
            }

            return postData.ToString();

        }

        private string CreateSign(IDictionary<string, string> parameters, string secret)
        {
            parameters.Remove("sign");

            IDictionary<string, string> sortedParams = new SortedDictionary<string, string>(parameters);
            IEnumerator<KeyValuePair<string, string>> dem = sortedParams.GetEnumerator();
            StringBuilder query = new StringBuilder(secret);

            while (dem.MoveNext())
            {
                string key = dem.Current.Key;

                string value = dem.Current.Value;
                if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(value))
                {
                    query.Append(key).Append(value);
                }
            }

            query.Append(secret);
            MD5 md5 = MD5.Create();
            byte[] bytes = md5.ComputeHash(Encoding.UTF8.GetBytes(query.ToString()));

            StringBuilder result = new StringBuilder();
            for (int i = 0; i < bytes.Length; i++)
            {
                string hex = bytes[i].ToString("X");
                if (hex.Length == 1)
                {
                    result.Append("0");
                }
                result.Append(hex);
            }
            return result.ToString();

        }



    }
}
